#include "App.h"
namespace XXD
{

    void App::Draw()
    {
    }
    void App::setTitle(const char *title)
    {
        glfwSetWindowTitle(m_Window, title);
    }
    void App::addModel(std::string name, std::shared_ptr<Model> Model)
    {
        m_Models[name] = Model;
    }
    App *App::getInstance()
    {
        static App _app;
        return &_app;
    }

    void App::run()
    {
        LOG_I("APP RUN");
        while (!glfwWindowShouldClose(m_Window))
        {
            processInput();
            glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
            Draw();
            for (auto &model : m_Models)
                model.second->Draw();
            glfwSwapBuffers(m_Window);
            glfwPollEvents();
        }
    }
    void App::framebuffer_size_callback(GLFWwindow *window, int width, int height)
    {
        LOG_I("framebuffer_size_callback");
    }
    void App::MouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
    {
        LOG_I("MouseButtonCallback");
    }
    void App::CursorPosCallback(GLFWwindow *window, double xpos, double ypos)
    {
        LOG_I("CursorPosCallback");
    }
    void App::ScrollCallback(GLFWwindow *window, double xoffset, double yoffset)
    {
        LOG_I("ScrollCallback");
    }
    App::~App()
    {
        glfwTerminate();
    }
    App::App()
    {
        glfwInit();
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        m_Window = glfwCreateWindow(m_width, m_height, "LearnOpenGL", NULL, NULL);
        if (m_Window == NULL)
        {
            LOG_E("Failed to create GLFW window");
            glfwTerminate();
            return;
        }
        glfwMakeContextCurrent(m_Window);
        if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
        {
            LOG_E("Failed to initialize GLAD");
            return;
        }
        glfwSetFramebufferSizeCallback(m_Window, framebuffer_size_callback);
        glfwSetMouseButtonCallback(m_Window, MouseButtonCallback);
        glfwSetCursorPosCallback(m_Window, CursorPosCallback);
        glfwSetScrollCallback(m_Window, ScrollCallback);
    }
    void App::processInput()
    {
        if (glfwGetKey(m_Window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(m_Window, true);
    }
}